/**
 * created by dt 2025-05-26
 * 优化版本的Attribute系统 - 针对高频modifier操作
 */

using System;
using System.Collections.Generic;
using UnityEngine;

namespace DLib.Attribute.Optimized
{
    /// <summary>
    /// 优化版本的属性系统 - 针对高频modifier操作
    /// </summary>
    [Serializable]
    public class OptimizedAttributes
    {
        // 基础数据存储
        private Dictionary<int, int> baseValues = new Dictionary<int, int>();
        private Dictionary<int, int> currentValues = new Dictionary<int, int>();
        private Dictionary<int, HashSet<int>> dependencies = new Dictionary<int, HashSet<int>>();
        
        // 修饰器存储
        private Dictionary<int, Dictionary<ModifierPriority, List<AttributeModifier>>> modifiers = 
            new Dictionary<int, Dictionary<ModifierPriority, List<AttributeModifier>>>();
        
        // 优化：批量操作支持
        private HashSet<int> pendingDirtyFlags = new HashSet<int>();
        private bool isBatchMode = false;
        private int batchVersion = 0;
        
        // 优化：缓存系统
        private Dictionary<int, int> calculatedValues = new Dictionary<int, int>();
        private Dictionary<int, int> calculationVersions = new Dictionary<int, int>();
        
        // 事件系统
        public event Action<int, int, int> OnAttributeChanged;

        #region 批量操作API

        /// <summary>
        /// 开始批量操作
        /// </summary>
        public void BeginBatch()
        {
            isBatchMode = true;
            batchVersion++;
            pendingDirtyFlags.Clear();
        }

        /// <summary>
        /// 结束批量操作，执行所有延迟的计算
        /// </summary>
        public void EndBatch()
        {
            isBatchMode = false;
            
            // 一次性处理所有脏标记
            foreach (var type in pendingDirtyFlags)
            {
                ProcessDirtyAttribute(type);
            }
            pendingDirtyFlags.Clear();
        }

        /// <summary>
        /// 批量添加修饰器
        /// </summary>
        public void AddModifiersBatch(Dictionary<int, List<AttributeModifier>> modifiersToAdd)
        {
            BeginBatch();
            
            foreach (var kvp in modifiersToAdd)
            {
                foreach (var modifier in kvp.Value)
                {
                    AddModifierInternal(kvp.Key, modifier);
                }
            }
            
            EndBatch();
        }

        /// <summary>
        /// 批量移除修饰器
        /// </summary>
        public void RemoveModifiersBatch(Dictionary<int, List<AttributeModifier>> modifiersToRemove)
        {
            BeginBatch();
            
            foreach (var kvp in modifiersToRemove)
            {
                foreach (var modifier in kvp.Value)
                {
                    RemoveModifierInternal(kvp.Key, modifier);
                }
            }
            
            EndBatch();
        }

        #endregion

        #region 优化的基础操作

        public void SetBaseValue(int type, int value)
        {
            int oldValue = GetCurrentValue(type);
            baseValues[type] = value;
            MarkDirtyOptimized(type);
            
            if (!isBatchMode)
            {
                int newValue = GetCurrentValue(type);
                if (oldValue != newValue)
                {
                    OnAttributeChanged?.Invoke(type, oldValue, newValue);
                }
            }
        }

        public int GetBaseValue(int type)
        {
            return baseValues.TryGetValue(type, out int value) ? value : 0;
        }

        public int GetCurrentValue(int type)
        {
            // 检查缓存
            if (calculatedValues.TryGetValue(type, out int cachedValue) &&
                calculationVersions.TryGetValue(type, out int version) &&
                version == batchVersion &&
                !pendingDirtyFlags.Contains(type))
            {
                return cachedValue;
            }

            // 需要重新计算
            if (pendingDirtyFlags.Contains(type))
            {
                ProcessDirtyAttribute(type);
            }

            return currentValues.TryGetValue(type, out int value) ? value : 0;
        }

        #endregion

        #region 优化的修饰器操作

        public AttributeModifier AddModifier(int type, AttributeModifier modifier)
        {
            AddModifierInternal(type, modifier);
            
            if (!isBatchMode)
            {
                ProcessDirtyAttribute(type);
            }
            
            return modifier;
        }

        private void AddModifierInternal(int type, AttributeModifier modifier)
        {
            if (!modifiers.ContainsKey(type))
            {
                modifiers[type] = new Dictionary<ModifierPriority, List<AttributeModifier>>();
            }

            var typeModifiers = modifiers[type];
            if (!typeModifiers.ContainsKey(modifier.Priority))
            {
                typeModifiers[modifier.Priority] = new List<AttributeModifier>();
            }

            typeModifiers[modifier.Priority].Add(modifier);
            MarkDirtyOptimized(type);
        }

        public void RemoveModifier(int type, AttributeModifier modifier)
        {
            RemoveModifierInternal(type, modifier);
            
            if (!isBatchMode)
            {
                ProcessDirtyAttribute(type);
            }
        }

        private void RemoveModifierInternal(int type, AttributeModifier modifier)
        {
            if (modifiers.TryGetValue(type, out var typeModifiers) &&
                typeModifiers.TryGetValue(modifier.Priority, out var priorityModifiers))
            {
                if (priorityModifiers.Remove(modifier))
                {
                    if (priorityModifiers.Count == 0)
                    {
                        typeModifiers.Remove(modifier.Priority);
                    }
                    if (typeModifiers.Count == 0)
                    {
                        modifiers.Remove(type);
                    }
                    MarkDirtyOptimized(type);
                }
            }
        }

        #endregion

        #region 优化的内部计算

        private void MarkDirtyOptimized(int type)
        {
            if (isBatchMode)
            {
                // 批量模式：只记录脏标记，不立即计算
                pendingDirtyFlags.Add(type);
                
                // 传播依赖关系
                if (dependencies.TryGetValue(type, out var deps))
                {
                    foreach (var dep in deps)
                    {
                        pendingDirtyFlags.Add(dep);
                    }
                }
            }
            else
            {
                // 非批量模式：立即标记为脏
                MarkDirtyImmediate(type);
            }
        }

        private void MarkDirtyImmediate(int type)
        {
            pendingDirtyFlags.Add(type);
            
            // 传播依赖关系
            if (dependencies.TryGetValue(type, out var deps))
            {
                foreach (var dep in deps)
                {
                    MarkDirtyImmediate(dep);
                }
            }
        }

        private void ProcessDirtyAttribute(int type)
        {
            if (!pendingDirtyFlags.Contains(type)) return;

            int oldValue = GetCurrentValue(type);
            int newValue = RecalculateValueOptimized(type);
            
            currentValues[type] = newValue;
            calculatedValues[type] = newValue;
            calculationVersions[type] = batchVersion;
            pendingDirtyFlags.Remove(type);

            if (oldValue != newValue)
            {
                OnAttributeChanged?.Invoke(type, oldValue, newValue);
            }
        }

        private int RecalculateValueOptimized(int type)
        {
            int baseValue = baseValues.TryGetValue(type, out int baseVal) ? baseVal : 
                           (currentValues.TryGetValue(type, out int currentVal) ? currentVal : 0);
            
            int finalValue = baseValue;

            if (modifiers.TryGetValue(type, out var typeModifiers))
            {
                // 按优先级排序处理
                var sortedPriorities = new List<ModifierPriority>(typeModifiers.Keys);
                sortedPriorities.Sort();

                foreach (var priority in sortedPriorities)
                {
                    var modifiers = typeModifiers[priority];
                    if (modifiers == null || modifiers.Count == 0) continue;

                    int totalFlat = 0;
                    int totalPercentage = 0;

                    // 收集当前优先级的所有修饰器效果
                    foreach (var modifier in modifiers)
                    {
                        switch (modifier.Type)
                        {
                            case ModifierType.Flat:
                                totalFlat += modifier.Value;
                                break;
                            case ModifierType.Percentage:
                                totalPercentage += modifier.Value;
                                break;
                            case ModifierType.Based:
                                if (modifier.BasedOnAttribute.HasValue)
                                {
                                    int basedOnValue = GetCurrentValue(modifier.BasedOnAttribute.Value);
                                    totalFlat += Mathf.RoundToInt(basedOnValue * (float)modifier.Value / AttributeModifier.PERCENTAGE_SCALE);
                                }
                                break;
                        }
                    }

                    // 应用当前优先级的效果
                    float percentageMultiplier = 1f + (float)totalPercentage / AttributeModifier.PERCENTAGE_SCALE;
                    finalValue = Mathf.RoundToInt((finalValue + totalFlat) * percentageMultiplier);
                }
            }

            return finalValue;
        }

        #endregion

        #region 工具方法

        public void Reset()
        {
            baseValues.Clear();
            currentValues.Clear();
            dependencies.Clear();
            pendingDirtyFlags.Clear();
            modifiers.Clear();
            calculatedValues.Clear();
            calculationVersions.Clear();
            isBatchMode = false;
            batchVersion = 0;
        }

        public HashSet<int> GetAllAttributeIds()
        {
            var ids = new HashSet<int>();
            foreach (var id in baseValues.Keys) ids.Add(id);
            foreach (var id in currentValues.Keys) ids.Add(id);
            foreach (var id in modifiers.Keys) ids.Add(id);
            return ids;
        }

        #endregion
    }

    /// <summary>
    /// 高性能Buff管理器
    /// </summary>
    public class BuffManager
    {
        private OptimizedAttributes attributes;
        private Dictionary<int, List<BuffInfo>> activeBuffs = new Dictionary<int, List<BuffInfo>>();
        private Queue<BuffInfo> buffPool = new Queue<BuffInfo>();
        private const int MAX_POOL_SIZE = 1000;

        public BuffManager(OptimizedAttributes attributes)
        {
            this.attributes = attributes;
        }

        /// <summary>
        /// 批量应用Buff
        /// </summary>
        public void ApplyBuffsBatch(Dictionary<int, List<BuffData>> buffsToApply)
        {
            attributes.BeginBatch();
            
            foreach (var kvp in buffsToApply)
            {
                int attributeId = kvp.Key;
                foreach (var buffData in kvp.Value)
                {
                    ApplyBuff(attributeId, buffData);
                }
            }
            
            attributes.EndBatch();
        }

        /// <summary>
        /// 应用单个Buff
        /// </summary>
        public BuffInfo ApplyBuff(int attributeId, BuffData buffData)
        {
            var buffInfo = GetBuffFromPool();
            buffInfo.Initialize(buffData);
            
            if (!activeBuffs.ContainsKey(attributeId))
            {
                activeBuffs[attributeId] = new List<BuffInfo>();
            }
            
            activeBuffs[attributeId].Add(buffInfo);
            
            // 添加修饰器
            var modifier = new AttributeModifier(
                buffData.type,
                buffData.value,
                ModifierPriority.Buff
            );
            
            buffInfo.modifier = modifier;
            attributes.AddModifier(attributeId, modifier);
            
            return buffInfo;
        }

        /// <summary>
        /// 移除Buff
        /// </summary>
        public void RemoveBuff(int attributeId, BuffInfo buffInfo)
        {
            if (activeBuffs.TryGetValue(attributeId, out var buffs))
            {
                if (buffs.Remove(buffInfo))
                {
                    attributes.RemoveModifier(attributeId, buffInfo.modifier);
                    ReturnBuffToPool(buffInfo);
                }
            }
        }

        /// <summary>
        /// 清理过期的Buff
        /// </summary>
        public void CleanupExpiredBuffs()
        {
            float currentTime = Time.time;
            var expiredBuffs = new List<(int attributeId, BuffInfo buffInfo)>();
            
            foreach (var kvp in activeBuffs)
            {
                int attributeId = kvp.Key;
                foreach (var buffInfo in kvp.Value)
                {
                    if (buffInfo.IsExpired(currentTime))
                    {
                        expiredBuffs.Add((attributeId, buffInfo));
                    }
                }
            }
            
            // 批量移除过期Buff
            if (expiredBuffs.Count > 0)
            {
                attributes.BeginBatch();
                
                foreach (var (attributeId, buffInfo) in expiredBuffs)
                {
                    RemoveBuff(attributeId, buffInfo);
                }
                
                attributes.EndBatch();
            }
        }

        private BuffInfo GetBuffFromPool()
        {
            if (buffPool.Count > 0)
            {
                return buffPool.Dequeue();
            }
            return new BuffInfo();
        }

        private void ReturnBuffToPool(BuffInfo buffInfo)
        {
            if (buffPool.Count < MAX_POOL_SIZE)
            {
                buffInfo.Reset();
                buffPool.Enqueue(buffInfo);
            }
        }
    }

    /// <summary>
    /// Buff信息
    /// </summary>
    public class BuffInfo
    {
        public ModifierType type;
        public int value;
        public float duration;
        public float startTime;
        public AttributeModifier modifier;

        public void Initialize(BuffData buffData)
        {
            type = buffData.type;
            value = buffData.value;
            duration = buffData.duration;
            startTime = Time.time;
        }

        public bool IsExpired(float currentTime)
        {
            return duration > 0 && (currentTime - startTime) >= duration;
        }

        public void Reset()
        {
            type = ModifierType.Flat;
            value = 0;
            duration = 0;
            startTime = 0;
            modifier = null;
        }
    }

    /// <summary>
    /// Buff数据
    /// </summary>
    [Serializable]
    public struct BuffData
    {
        public ModifierType type;
        public int value;
        public float duration;
    }
} 